<template>
  <div class="container">
    <div class="app-container">
      <!-- 角色管理内容 -->
      <div class="role-operate">
        <el-button type="primary" @click="addRoleDialogVisible = true">添加角色</el-button>
      </div>
      <!-- 放置table租金 -->
      <el-table :data="roleList">
        <!-- 放置列 -->
        <el-table-column prop="name" label="角色" width="200" align="center">
          <template v-slot="{ row }">
            <!-- 条件判断 -->
            <el-input v-if="row.isEdit" v-model="row.editRow.name" size="mini"></el-input>
            <span v-else>{{ row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="state" label="启用" width="200" align="center">
          <!-- 自定义列结构 -->
          <template v-slot="{ row }">
            <!-- 开 1 关0 -->
            <el-switch
              v-if="row.isEdit"
              v-model="row.editRow.state"
              :active-value="1"
              :inactive-value="0"
              active-color="#13ce66"
            ></el-switch>
            <span v-else>{{ row.state === 1 ? '已启用' : row.state === 0 ? '未启用' : '无' }} </span>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="描述" align="center">
          <template v-slot="{ row }">
            <el-input
              v-if="row.isEdit"
              v-model="row.editRow.description"
              size="mini"
              type="textarea"
            ></el-input>
            <span v-else>{{ row.description }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="address" label="操作" align="center">
          <template v-slot="{ row }">
            <!-- 编辑状态 -->
            <template v-if="row.isEdit">
              <el-button type="primary" size="mini" @click="editBtnOk(row)">确认</el-button>
              <el-button type="info" size="mini" @click="row.isEdit = false">取消</el-button>
            </template>
            <!-- 非编辑状态 -->
            <template v-else>
              <el-button type="text" size="mini" @click="assignPermissionBtn(row.id)">分配权限</el-button>
              <el-button type="text" size="mini" @click="editBtnRow(row)">编辑</el-button>
              <el-popconfirm title="确定删除该角色吗?" @onconfirm="delRoleBtn(row.id)">
                <el-button slot="reference" type="text" size="mini" style="margin-left: 10px"
                  >删除</el-button
                >
              </el-popconfirm>
            </template>
          </template>
        </el-table-column>
      </el-table>
      <el-row type="flex" style="height: 60px" align="middle" justify="end">
        <el-pagination
          :current-page="pageParams.page"
          :page-size="pageParams.pagesize"
          :total="pageParams.total"
          layout="prev, pager, next"
          @current-change="changePage"
        >
        </el-pagination>
      </el-row>
    </div>
    <!-- 添加角色弹窗 -->
    <el-dialog title="添加角色" :visible="addRoleDialogVisible" width="500px" :before-close="btnCancel">
      <el-form ref="roleFormRef" :model="roleForm" :rules="roleRules" size="mini" label-width="120px">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="roleForm.name" placeholder="请输入角色名称" style="width: 300px"></el-input>
        </el-form-item>
        <el-form-item label="启用">
          <el-switch
            v-model="roleForm.state"
            :active-value="1"
            :inactive-value="0"
            active-color="#13ce66"
            size="mini"
          >
          </el-switch>
        </el-form-item>
        <el-form-item label="角色描述" prop="description">
          <el-input
            v-model="roleForm.description"
            placeholder="请输入角色描述"
            type="textarea"
            :row="4"
            style="width: 300px"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-row type="flex" justify="center">
            <el-col :span="12">
              <el-button type="primary" @click="addRoleBtn">确定</el-button>
              <el-button @click="btnCancel">取消</el-button>
            </el-col>
          </el-row>
        </el-form-item>
      </el-form>
    </el-dialog>
    <!-- 分配角色权限对话框 -->
    <el-dialog
      title="提示"
      :visible.sync="assignRolePerDialogVisible"
      width="500px"
      :before-close="assignRolePerCancelBtn"
    >
      <el-tree
        ref="permTree"
        :data="PermissionListData"
        :props="{ label: 'name' }"
        show-checkbox
        node-key="id"
        :default-checked-keys="permissionId"
        default-expand-all
      >
      </el-tree>
      <el-row slot="footer" type="flex" justify="center">
        <el-col :span="6">
          <el-button @click="assignRolePerCancelBtn">取 消</el-button>
          <el-button type="primary" @click="assignPermissionBtnOk">确 定</el-button>
        </el-col>
      </el-row>
    </el-dialog>
  </div>
</template>
<script>
import {
  getRoleListData,
  addRole,
  updateRoleData,
  delRoleData,
  getRoleDetail,
  assignPrem
} from '@/api/role.js'
import { getPermissionList } from '@/api/permission.js'
import { tranListToTreeData } from '@/utils'
export default {
  name: 'Role',
  data() {
    return {
      roleList: [], // 角色列表
      pageParams: {
        // 分页参数
        page: 1, // 当前页码
        pagesize: 5, // 每页显示条数
        total: 0 // 总条数
      },
      addRoleDialogVisible: false, // 控制添加角色弹窗的显示
      roleForm: {
        // 角色表单数据
        name: '',
        state: 0, // 启用状态，1为开启，0为关闭
        description: '' // 角色描述
      },
      roleRules: {
        name: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
        description: [{ required: true, message: '角色描述不能为空', trigger: 'blur' }]
      }, // 角色表单验证规则
      assignRolePerDialogVisible: false, // 控制分配角色权限对话框的显示
      currentRoleId: '', // 当前角色ID，用于分配权限时使用
      PermissionListData: [], // 树形权限列表数据
      permissionId: [] // 当前权限ID，用于分配权限时使用
    }
  },
  created() {
    // 初始化时获取角色列表数据
    this.getRoleList()

    //绑定分页
    //初始化时请求第一页
    //切换分页请求对应数据
  },
  methods: {
    // 获取角色列表数据
    async getRoleList() {
      const { rows, total } = await getRoleListData(this.pageParams)
      this.roleList = rows
      this.pageParams.total = total // 更新总条数
      //获取数据之后针对每个数据添加一个编辑标记-使用$set 来保证响应式更新 this.$set(目标对象, 属性名称, 初始值)
      this.roleList.forEach(item => {
        this.$set(item, 'isEdit', false) // 初始化时将列表的所有数据设置为非编辑状态，以便后续可以进行编辑操作
        this.$set(item, 'editRow', {
          //初始化时缓存编辑行数据，以便在编辑状态下恢复原始数据
          name: item.name,
          state: item.state,
          description: item.description
        })
      })
    },
    // 分页切换事件
    changePage(newPage) {
      this.pageParams.page = newPage // 更新当前页码
      this.getRoleList() // 重新获取角色列表数据
    },
    // 添加角色按钮事件
    addRoleBtn() {
      try {
        // 表单验证，只有当表单验证通过时才执行添加角色的操作
        this.$refs.roleFormRef.validate(async valid => {
          if (valid) {
            const res = await addRole(this.roleForm) // 调用添加角色的接口
            // console.log(res)
            // 关闭弹窗
            this.btnCancel()
            this.$message.success('新增角色成功')
            // 重新获取角色列表数据
            this.getRoleList()
          }
        })
      } catch (error) {
        this.$message.error('新增角色失败')
      }
    },
    // 添加角色取消按钮事件
    btnCancel() {
      this.addRoleDialogVisible = false // 关闭弹窗
      this.$refs.roleFormRef.resetFields() // 重置表单校验和数据
    },
    // 点击进入编辑行状态事件。 点击进入编辑状态时需将原始数据缓存到编辑行的对象中,编辑状态将编辑状态数据缓存到默认显示状态数据row对象中
    editBtnRow(row) {
      row.isEdit = !row.isEdit // 切换编辑行数据为编辑状态
      // 1、 点击编辑时更新缓存数据，将原始数据缓存到editRow对象中
      row.editRow = {
        name: row.name,
        state: row.state,
        description: row.description
      }
    },
    // 编辑状态确认更新角色数据事件
    async editBtnOk(row) {
      // console.log(row)
      //角色和角色描述数据不能为空才能更新
      if (row.editRow.name && row.editRow.description) {
        await updateRoleData({ ...row.editRow, id: row.id })
        row.isEdit = !row.isEdit // 将当前行设置为非编辑状态
        this.$message.success('更新角色成功！')
        //2、 更新默认显示数据 退出编辑状态
        Object.assign(row, {
          //点击进入编辑状态时需将原始数据缓存到编辑行的对象中,编辑状态将编辑状态数据缓存到默认显示状态数据row对象中
          ...row.editRow,
          isEdit: false //退出编辑状态
        })
      } else {
        this.$message.error('角色和角色描述不能为空！')
      }
    },
    // 删除角色事件
    async delRoleBtn(id) {
      await delRoleData(id) //调用删除角色的接口
      this.$message.success('删除角色成功！')
      // 如果当前页只有一条数据，则将当前页码减1，以便在删除后能够显示上一页的数据
      if (this.list.length === 1) {
        this.pageParams.page--
      } else this.pageParams.page = 1 //否则重置为第一页，以便在删除后能够显示第一页的数据
      this.getRoleList() //重新获取角色列表数据
    },
    // 分配角色权限事件
    async assignPermissionBtn(id) {
      //记录当前分配角色id
      this.currentRoleId = id
      //获取所有权限列表数据，并转换为树形结构数据
      this.PermissionListData = tranListToTreeData(await getPermissionList(), 0)
      // console.log(this.PermissionListData)
      //获取角色已有权限列表数据
      const { permIds } = await getRoleDetail(id)
      //保存当前角色已有权限id列表，以便在树形控件中选中这些已分配的权限 ref="permTree"
      // <el-tree
      //   ref="permTree"
      //   :data="PermissionListData"
      //   :props="{ label: 'name' }"
      //   show-checkbox
      //   node-key="id"
      //   :default-checked-keys="permissionId"
      //   default-expand-all
      // >
      // </el-tree>
      this.permissionId = permIds
      this.assignRolePerDialogVisible = true
    },
    // 分配角色权限确定按钮事件
    async assignPermissionBtnOk() {
      //分配角色权限接口调用，将当前角色的id和选中的权限ids传递给后端
      await assignPrem({ id: this.currentRoleId, permIds: this.$refs.permTree.getCheckedKeys() })
      this.assignRolePerDialogVisible = false
      this.$message.success('分配角色权限成功！')
    },
    // 分配角色权限取消按钮事件
    assignRolePerCancelBtn() {
      this.assignRolePerDialogVisible = false
    }
  }
}
</script>
<style scoped lang="scss">
.role-operate {
  padding: 10px;
}
</style>
